package com.imooc.rabbitmq.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

/**
 * The class JacksonUtil
 *
 * json字符与对像转换
 * 
 *
 */
public class JacksonUtil {

	public static ObjectMapper objectMapper;

	/**
	 * 使用泛型方法，把json字符串转换为相应的JavaBean对象。
	 * (1)转换为普通JavaBean：readValue(json,Student.class)
	 * (2)转换为List,如List<Student>,将第二个参数传递为Student
	 * [].class.然后使用Arrays.asList();方法把得到的数组转换为特定类型的List
	 * 
	 * @param jsonStr
	 * @param valueType
	 * @return
	 */
	public static <T> T readValue(String jsonStr, Class<T> valueType) {
		if (objectMapper == null) {
			objectMapper = new ObjectMapper();
		}

		try {
			return objectMapper.readValue(jsonStr, valueType);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * json数组转List
	 * 
	 * @param jsonStr
	 * @param valueTypeRef
	 * @return
	 */
	public static <T> T readValue(String jsonStr, TypeReference<T> valueTypeRef) {
		if (objectMapper == null) {
			objectMapper = new ObjectMapper();
		}

		try {
			return objectMapper.readValue(jsonStr, valueTypeRef);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 把JavaBean转换为json字符串
	 * 
	 * @param object
	 * @return
	 */
	public static String toJSon(Object object) {
		if (objectMapper == null) {
			objectMapper = new ObjectMapper();
		}

		try {
			return objectMapper.writeValueAsString(object);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public static boolean isEmpty(Object obj) {
		boolean result = true;
		if (obj == null) {
			return true;
		}
		if (obj instanceof String) {
			result = (obj.toString().trim().length() == 0) || obj.toString().trim().equals("null");
		} else if (obj instanceof Collection) {
			result = ((Collection) obj).size() == 0;
		} else {
			result = ((obj == null) || (obj.toString().trim().length() < 1)) ? true : false;
		}
		return result;
	}

	private static ObjectMapper getMapperInstance(boolean createNew) {
		if (createNew) {
			return new ObjectMapper();
		} else if (objectMapper == null) {
			objectMapper = new ObjectMapper();
		}
		return objectMapper;
	}

	/**
	 * 获取对应路径下的json节点对应的属性值列表
	 * @param json
	 * @param tagPath 形如：topologyJson:childs:childs:id
	 * @return
	 * @throws Exception
	 */
	public static List<String> readValueFromJson(String json, String tagPath) throws Exception {
		// 返回值
		List<String> value = new ArrayList<String>();
		if (isEmpty(json) || (isEmpty(tagPath))) {
			return value;
		}
		ObjectMapper mapper = getMapperInstance(false);
		String[] path = tagPath.split(":");
		JsonNode node = mapper.readTree(json);
		getJsonValue(node, path, value, 1);
		return value;
	}

	private static void getJsonValue(JsonNode node, String[] path, List<String> values, int nextIndex) {
		if (isEmpty(node)) {
			return;
		}
		// 是路径的最后就直接取值
		if (nextIndex == path.length) {
			if (node.isArray()) {
				for (int i = 0; i < node.size(); i++) {
					JsonNode child = node.get(i).get(path[nextIndex - 1]);
					if (isEmpty(child)) {
						continue;
					}
					values.add(child.toString());
				}
			} else {
				JsonNode child = node.get(path[nextIndex - 1]);
				if (!isEmpty(child)) {
					values.add(child.toString());
				}
			}
			return;
		}
		// 判断是Node下是集合还是一个节点
		node = node.get(path[nextIndex - 1]);
		if (node.isArray()) {
			for (int i = 0; i < node.size(); i++) {
				getJsonValue(node.get(i), path, values, nextIndex + 1);
			}
		} else {
			getJsonValue(node, path, values, nextIndex + 1);
		}
	}
	
	/**
	 * 获取对应路径下的json节点元素列表
	 * @param json
	 * @param tagPath 形如：topologyJson:childs:childs
	 * @return
	 * @throws Exception
	 */
	public static List<JsonNode> readNodeFromJson(String json, String tagPath) throws Exception {
		// 返回值
		List<JsonNode> value = new ArrayList<JsonNode>();
		if (isEmpty(json) || (isEmpty(tagPath))) {
			return value;
		}
		ObjectMapper mapper = getMapperInstance(false);
		String[] path = tagPath.split(":");
		JsonNode node = mapper.readTree(json);
		getJsonNode(node, path, value, 1);
		return value;
	}

	private static void getJsonNode(JsonNode node, String[] path, List<JsonNode> values, int nextIndex) {
		if (isEmpty(node)) {
			return;
		}
		// 是路径的最后就直接取值
		if (nextIndex == path.length) {
			JsonNode child = node.get(path[nextIndex - 1]);
			if (child.isArray()) {
				for (int i = 0; i < child.size(); i++) {
					JsonNode childone = child.get(i);
					if (isEmpty(childone)) {
						continue;
					}
					values.add(childone);
				}
			} else {
				if (!isEmpty(child)) {
					values.add(child);
				}
			}
			return;
		}
		// 判断是Node下是集合还是一个节点
		node = node.get(path[nextIndex - 1]);
		if (node.isArray()) {
			for (int i = 0; i < node.size(); i++) {
				getJsonNode(node.get(i), path, values, nextIndex + 1);
			}
		} else {
			getJsonNode(node, path, values, nextIndex + 1);
		}
	}

}